/**
 * 导入公共逻辑
 */
const {
  BASE_API,
  ENV_FORMAL
} = process.env;

import { enter2Br, aesDecode } from '@/utils/string';
import axios from 'axios';
import store from '@/store';
import { getToken } from '@/utils/auth';
import { getUpToken } from '@/api/qiniu';
import * as qiniu from 'qiniu-js';
import { SECRET_KEY, INNER_ADDRESS } from '@/utils/const';
import ElMessage from '@/utils/message';

export default {
  data() {
    return {
      loading: false,
      CancelAxios: null,
      maxVirtualPercent: 90,
      timer: '',
      uploadPercent: 0,
      isLt5M: false,
      subscription: null,
      filePercent: {

      }
    };
  },
  methods: {
    async beforeUpload(file) {
      const temp = this.fileType.replace(/\|/g, '、');
      this.$emit('beforeUpload', { file });
      const reg = new RegExp(this.fileType);
      if (this.validateUpload) {
        const isPass = await this.validateUpload(file);
        if (!isPass) return;
      }
      if (this.fileType && !reg.test(file.name)) {
        this.$message.warning(`仅支持上传 ${temp} 类型的文件`);
        return false;
      }

      if (!this.titleBg) {
        const fileNameTemp = file.name.replace(/\.xl(s|s[xmb]|t[xm]|am)$/, '');
        fileNameTemp.length > 100 ? this.limitNum = true : this.limitNum = false; // 判断文件名的长度
        this.isLt5M = file.size / 1024 / 1024 <= this.limitFileSize;
        if (!this.isLt5M) {
          this.$message.error(`上传的文件不能超过${this.limitFileSize}MB!`);
          this.$emit('onError', `上传的文件不能超过${this.limitFileSize}MB!`);
        }

        return this.isLt5M;
      } else {
        const isJPG = file.type === 'image/jpeg';
        const isPNG = file.type === 'image/png';
        const isGIF = file.type === 'image/gif';
        const isLt2M = file.size / 1024 / 1024 < 2;
        this.isUpload = true;
        if (!isJPG && !isPNG && !isGIF) {
          this.$message.error('图片只能是 JPG/PNG/GIF 格式!');
          this.isUpload = false;
          return false;
        }
        if (!isLt2M) {
          this.$message.error('图片大小不能超过 2MB!');
          this.isUpload = false;
          return false;
        }
        return (isJPG || isPNG || isGIF) && isLt2M;
      }
    },
    uploadFileMethod(param) {
      const fileObject = param.file;
      const fileName = fileObject.name || '';
      // 上传类型：0:通过服务端上传 1:前端直接上传
      if (this.uploadType === 1) {
        this.qiniuUpload({ file: fileObject, fileName, ...this.extendParams }, this.getList);
      } else {
        this.toUploadHttp({ fileObject, fileName });
      }
    },
    // 服务端上传
    importList(service, url, formData, getListfun, source, originName) {
      this.loading = true;
      this.$emit('upProgress');
      service.post(url, formData, {
        cancelToken: source.token || null
      }).then(({ data }) => {
        this.loading = false;
        if (data.code === 200) {
          const fileName = formData.get('fileName');
          delete this.filePercent[fileName];
          if (data.data && !data.data.name) data.data.name = fileName;
          data.data._originName = originName;
          this.handelCallback(data, getListfun);
          if (this.uploadFinish) this.uploadFinish(fileName);
        } else {
          throw new Error(data.message);
        }
      }).catch((err) => {
        const fileName = formData.get('fileName');
        delete this.filePercent[fileName];
        if (this.uploadFinish) this.uploadFinish(fileName);

        this.loading = false;
        console.log(err);
        if (this.timer) clearInterval(this.timer); // 清除虚拟进度
        this.uploadPercent = 0; // 上传完后清除进度条
        let errMsg = typeof err === 'object' ? err.message : err;
        if (errMsg.indexOf('timeout') >= 0) {
          errMsg = '文件较大，拼命导入中，请半小时后进入系统查看导入结果';
        } else {
          const chineseRegex = /^[\u4e00-\u9fa5]$/;
          errMsg = (errMsg && chineseRegex.test(errMsg.charAt(0)) ? errMsg : '文件上传失败，请重新上传');
          this.$message.warning(errMsg);
        }
        this.$emit('onError', errMsg || '请求失败');
        if (this.errorFileListChange) this.errorFileListChange(formData, err, originName);
      });
    },
    serviceToken(service) {
      service.interceptors.request.use(
        config => {
          const token = store.getters.token || getToken();
          if (token) {
            config.headers.common['token'] = token;
          }
          return config;
        },
        error => {
          console.log(error);
          Promise.reject(error);
        }
      );
      service.interceptors.response.use(response => {
        if (response && response.data && typeof response.data === 'string') {
          const decodeStr = aesDecode(response.data, SECRET_KEY);
          try {
            response.data = typeof decodeStr === 'string' ? JSON.parse(decodeStr) : decodeStr;
          } catch (error) {
            response.data = decodeStr;
          }
        }
        return response;
      });
    },
    toUploadHttp({ fileObject, fileName }) {
      const that = this;
      const formData = new FormData();
      formData.append('fileData', fileObject);
      if (this.uploadId && this.uploadId !== '') {
        formData.append('uploadId', this.uploadId);
      }
      let fileNameData;
      if (this.useOriginName) {
        formData.append('fileName', fileName);
      } else if (fileName) {
        const fileExtension = fileObject.name.split('.').pop();
        fileNameData = `${new Date().valueOf()}_${Math.ceil(Math.random() * 99999)}.${fileExtension}`;

        formData.append('fileName', fileNameData);
      }
      const isError = this.getIsError();
      if (isError) {
        return;
      }
      if (this.setPriviewImg) {
        this.setPriviewImg({ fileObject, fileName: fileNameData || fileName, originName: fileName });
      }
      if (this.extendParams) {
        for (const key in this.extendParams) {
          if (this.extendParams.hasOwnProperty(key)) {
            const element = this.extendParams[key];
            formData.append(key, element);
          }
        }
      }
      // 使用附件内网上传，需要增加参数识别，用于区分上传后的文件保存位置
      if (this.useInnerUpload) {
        console.log('envInfo:', process.env, ENV_FORMAL);
        formData.append('useInner', ENV_FORMAL ? '0' : '1');
      }
      this.timer = setInterval(() => { // 开始虚拟进度
        if (this.uploadPercent <= this.maxVirtualPercent) this.uploadPercent += 1;
        else clearInterval(this.timer);
      }, 80);
      var source = axios.CancelToken.source();
      const baseURL = this.useInnerUpload ? INNER_ADDRESS : BASE_API;
      const service = axios.create({
        baseURL, // api 的 base_url
        timeout: 3600000, // 请求超时时间
        // timeout: 60000,
        headers: {
          'Content-Type': 'multipart/form-data;'
        },
        onUploadProgress: function(progressEvent) { // 获取进度条
          if (!that.filePercent[fileNameData]) {
            that.$set(that.filePercent, fileNameData, 1);
          }
          if (progressEvent.lengthComputable) {
            // if (that.timer) clearInterval(that.timer);
            const lastPercent = that.uploadPercent ? that.uploadPercent : 0;
            const total = progressEvent.total;
            const loaded = progressEvent.loaded;
            const uploadPercent = parseInt(loaded / total * 100);
            that.uploadPercent = lastPercent >= uploadPercent ? lastPercent : uploadPercent;
            that.$set(that.filePercent, fileNameData, uploadPercent);
            if (that.uploadPercent === 100) {
              setTimeout(() => {
                that.uploadPercent = 0;
              }, 1000);
            }
          }
        }
      });
      this.cancelAxios = source;
      this.serviceToken(service);
      this.importList(service, this.importApi, formData, this.getList, source, fileName);
    },
    // 服务端上传 end
    // 直接七牛云上传
    async qiniuUpload(params, getListfun) {
      const isError = this.getIsError();
      if (isError) {
        return;
      }
      try {
        const that = this;
        const tokenData = await this.getQiniuToekn();
        let bucketHost = tokenData.bucketHost;
        bucketHost = bucketHost.endsWith('/') ? bucketHost : bucketHost + '/';
        // 设置文件的配置;
        const putExtra = {
          fname: params.fileName
        };
        this.$emit('upProgress');
        this.loading = true;
        const observable = qiniu.upload(params.file, null, tokenData.token, putExtra, {});
        const observer = {
          next(res) {
            // 上传进度
            that.uploadPercent = parseInt(res.total.percent);
          },
          complete(res) {
            const ans = {
              code: 200,
              data: {
                name: params.fileName,
                time: new Date().valueOf(),
                url: `${bucketHost}${res.key}`
              },
              message: '请求成功'
            };
            that.handelCallback(ans, getListfun);
          },
          error(err) {
            that.handelCallback({ code: 500, message: err }, getListfun);
            this.$emit('upLoadError');
          }
        };
        this.subscription = observable.subscribe(observer);
      } catch (error) {
        console.log(error);
      }
    },
    getQiniuToekn() {
      return new Promise((resolve, reject) => {
        getUpToken().then(res => {
          if (res.data) {
            resolve(res.data);
          } else {
            reject(res);
          }
        }).catch(err => {
          reject(err);
        });
      });
    },
    // 直接七牛云上传 end
    /** tool */
    // 上传前验证限制
    getIsError() {
      let isError = false;
      let errMsg = '';
      if (!this.titleBg) {
        if (!this.isLt5M && this.limitNum) { // 判断文件的大小以及文件的名称
          errMsg = `上传的文件不能超过${this.limitFileSize}MB且文件名称不得超过100个字!`;
          isError = true;
        } else if (!this.isLt5M) {
          errMsg = `上传的文件不能超过${this.limitFileSize}MB!`;
          isError = true;
        } else if (this.limitNum) {
          errMsg = '文件名称超过100个字，请修改后再试';
          isError = true;
        }
      } else if (!this.isUpload) {
        isError = true;
      }
      if (isError) {
        if (errMsg) {
          ElMessage.error(errMsg);
          this.$emit('onError', errMsg);
        }
        if (this.timer) clearInterval(this.timer); // 清除虚拟进度
      }
      return isError;
    },
    // 上传完成处理
    handelCallback(res, getListfun) {
      /**
       * res.data
       * name: 文件名称
       * time
       * url
       */
      this.loading = false;
      this.$emit('complateSetData', { data: res.data, fileName: res.data ? res.data._originName || res.data.name : '', processName: res.data.name, message: res.message });
      this.uploadPercent = 100; // 在导入失败后进度条总还是100
      if (res.code === 200) {
        if (this.timer) clearInterval(this.timer); // 清除虚拟进度
        this.uploadPercent = 0; // 上传完后清除进度条
        if (getListfun) getListfun();
      } else {
        this.$emit('onError', res.message);
        this.$confirm(enter2Br(res.message), '', {
          confirmButtonText: '确定',
          showCancelButton: false,
          showClose: true,
          type: 'warning',
          center: true,
          iconClass: 'charge-icon',
          customClass: 'charge-message-box',
          dangerouslyUseHTMLString: true
        }).then(() => {
          if (this.timer) clearInterval(this.timer); // 清除虚拟进度
          this.uploadPercent = 0; // 上传完后清除进度条
        }).catch(() => {
          if (this.timer) clearInterval(this.timer); // 清除虚拟进度
          this.uploadPercent = 0; // 上传完后清除进度条
        });
      }
    },
    cancelHttp(msg = '请求已取消') {
      if (this.cancelAxios) {
        this.cancelAxios.cancel(msg);
      }
      if (this.subscription) {
        this.subscription.unsubscribe();
      }
    }
  }
};
